package com.osdp.gateway.config;

import com.alibaba.nacos.api.PropertyKeyConst;
import com.alibaba.nacos.api.config.ConfigFactory;
import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.api.exception.NacosException;
import com.osdp.gateway.predicate.TokenCheckRoutePredicateFactory;
import com.osdp.gateway.repository.NacosDynamicRouteRepository;
import com.osdp.gateway.resolver.HostAddrKeyResolver;
import com.osdp.gateway.service.IRouteService;
import com.osdp.gateway.service.impl.RouteServiceImpl;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.Properties;

/**
 * 动态路由配置
 * ConditionalOnProperty控制配置类是否生效,控制@Configuration是否生效.
 * 可以将配置与代码进行分离,实现了更好的控制配置,实现是通过havingValue与配置文件中的值对比,返回为true则配置类生效,反之失效.
 */
@Configuration
@EnableConfigurationProperties(OsdpGatewayProperties.class)
@ConditionalOnProperty(prefix = "osdp.gateway.dynamic-route", name="enabled", havingValue = "true")
public class DynamicRouteConfig {
    /**
     * 动态路由生效时配置信息
     */
    @Configuration
    @ConditionalOnProperty(prefix = "osdp.gateway.dynamic-route", name = "dataType", havingValue = "nacos")
    public class NacosDyRoute{
        @Bean
        public NacosDynamicRouteRepository nacosDynamicRouteRepository(){
            return new NacosDynamicRouteRepository();
        }

        @Bean
        public IRouteService routeService(){
            return new RouteServiceImpl();
        }
    }

    /**
     * 配置中心服务
     * @param gatewayProperties
     * @return
     * @throws NacosException
     */
    @Bean
    public ConfigService nacosConfigService(OsdpGatewayProperties gatewayProperties) throws NacosException {
        Properties properties = new Properties();
        properties.put(PropertyKeyConst.SERVER_ADDR,gatewayProperties.getServerAddr());
        properties.put(PropertyKeyConst.NAMESPACE,gatewayProperties.getNamespace());
        ConfigService configService = ConfigFactory.createConfigService(properties);
        return configService;
    }

    /**
     * 自定义token验证工厂
     * @return
     */
    @Bean
    public TokenCheckRoutePredicateFactory tokenCheckRoutePredicateFactory(){
        return new TokenCheckRoutePredicateFactory();
    }

    /**
     * 令牌桶根据IP地址限制
     * @return
     */
    @Bean
    public HostAddrKeyResolver hostAddrKeyResolver(){
        return new HostAddrKeyResolver();
    }
}
